package org.jeecg.modules.system.rule;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang.math.RandomUtils;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.handler.IFillRuleHandler;
import org.jeecg.common.util.CodeUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.manage.entity.SysSerialNumberConfig;
import org.jeecg.modules.manage.service.ISysSerialNumberConfigService;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

/**
 * 编码 针对公司目前产品货号没有一个统一的标准，根据经验：可以按两个大类来分，一个是公司研发新欲，一个是客户定制新软，由 CAD
 * 设计部分进行新款编号并统一记录，出 CAD 的时候就可以同步进行编号。统一的编号规律很有利于以后区分新欲旧欲以及区分客户欲式，也方便 ERp 系统的管理。
 * 公司研发新欲统一以 AN 开头： ANR2ll000o , ( 000 刀 0003 … … 依次推进 ( R 代表戒指编号：‘卜 I ' ul4 位数
 * 2110 代表 21 年 10 月份新款） ANEZ " c000 , ( 000210003 … ，．依次推进 ( E 代表耳环编号：中间 4 位数
 * 2110 代及 21 年 10 月份新款） ANN2ll000ol ( 000 刀 0003 . ． … 依次推进 ( N 代表项链编号：中间 4 位数
 * 2110 代表 21 年 10 月份新款） ANBZ " 00001 ( 000210003 . ． … 依次推进 ( B 代农手链编号： , ! ,
 * rf , J4 位数 2110 代表 21 年 10 月份新救） ANo211cooo1 ( oo02lOoo3 . ． … 依次推进 《 O
 * 代表其他特殊款式编号：中间 4 位数 2110 代表 21 年 10 月份新款） ANS21 100001 一 RIEINIB … （ 000210003
 * . ． … 依次推进 《 S 代表套装编号．后面的 · RIEINIB 等代表此套装的戒指，吊哈．耳环等．中间 4 位数 21 10 代表 21 年 10
 * 月份新款）如果一开始单款只是设计了一款戒指 l 耳环 I 项链，后面设计配套的款式，则需要件款号变更为套装编号．例如： ANR211 以力 01
 * 后期设计配套款式．款号则变更为 ANS21 100001 一 R
 * 
 * 2 、客户研发新款统以客户代码开头：同理，客户定制狱式将编号开头的 AN 换成客户代码开头，比如 OR21 09001 。 ERp 可以同时记录相应的 O
 * 教是哪个客户编号的，业务员应该知道哪些客户编号下的 O 欲是不可以推荐给其他客户挑选的，这样可以进免很多问肠和节省沟通成本。 R-戒指 N-项链 E-耳环
 * B-手链手镯 O-其他特殊款式，例如胸针 耳塞之类
 */
public class StyleCodeNumberRule implements IFillRuleHandler {

	@Override
	public Object execute(JSONObject params, JSONObject formData) {

		System.out.println("formData:" + formData.toJSONString());

		RedisTemplate redisTemplate = SpringContextUtils.getBean("redisTemplate", RedisTemplate.class);
		String code = ""; // 最终编码
		String codeKey = ""; // 对应编码的Key
		String prefix = "AN"; // 对应编码的前缀,默认 code num 缩写
		String styleType = "O";

		int codeSerialNumberLen = 4; // 对应编码流水号长度，默认为4
		String maxCode = ""; // 目前最大编码

		if (params != null) {
			Object obj = params.get("codeKey");
			if (oConvertUtils.isNotEmpty(obj))
				codeKey = obj.toString();
		}
		
	
		ISysSerialNumberConfigService sysSerialNumberConfigService = (ISysSerialNumberConfigService) SpringContextUtils
				.getBean("sysSerialNumberConfigServiceImpl");
		LambdaQueryWrapper<SysSerialNumberConfig> query = new LambdaQueryWrapper<SysSerialNumberConfig>()
				.eq(SysSerialNumberConfig::getCodeTag, codeKey);
		SysSerialNumberConfig sysSerialNumberConfigObj = sysSerialNumberConfigService.getOne(query);

		// 取自定义前缀
		if (sysSerialNumberConfigObj != null) {
			prefix = sysSerialNumberConfigObj.getCodePrefix();
			codeSerialNumberLen = sysSerialNumberConfigObj.getCodeLength();
		}
		
		
		//如果所属客户不为空则为客户款式
		if(formData.get("customer")!=null)
		{
			prefix= String.valueOf(formData.get("customer"));
		}


		// 取款式类别
		ISysDictService sysDictService = (ISysDictService) SpringContextUtils.getBean("sysDictServiceImpl");
		styleType = sysDictService.queryDictTextByKey("style_type", String.valueOf(formData.get("style_cate")));
		String styleTypeCode = "O";
		if (styleType.contains("耳")) {
			styleTypeCode = "E";
		} else if (styleType.contains("手")) {
			styleTypeCode = "B";
		} else if (styleType.contains("戒")) {
			styleTypeCode = "R";
		} else if (styleType.contains("项") || styleType.contains("颈")) {
			styleTypeCode = "N";
		}

		// 获取日期
		SimpleDateFormat format = new SimpleDateFormat("yyMM");
		String dateString = format.format(new Date());

		// 获取目前最大编码

		Object maxCodeObj = redisTemplate.opsForValue().get(codeKey);

		if (!oConvertUtils.isEmpty(maxCodeObj))
			maxCode = maxCodeObj.toString();

		if (maxCode == null || maxCode == "" || maxCode.equals("")) {
			code = CodeUtil.getNextCode(null, prefix, styleTypeCode, dateString, codeSerialNumberLen);
		} else {

			code = CodeUtil.getNextCode(maxCode, prefix, styleTypeCode, dateString, codeSerialNumberLen);
		}

		redisTemplate.opsForValue().set(codeKey, code); // 更新redis中的最大编码值

		return code;
	}

}
